package org.linuxsogood.boot.nio;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author liu.hongwei
 */
@Slf4j
public class BioServer {


    public static void main(String[] args) throws IOException {

        List<Socket> clientList = new ArrayList<>();

        ExecutorService executorService = Executors.newCachedThreadPool();

        ServerSocket serverSocket = new ServerSocket(6666);

        while (true) {
            Socket clientSocket = serverSocket.accept();
            clientList.add(clientSocket);
            log.info("接入一个客户端:{}, 当前有[{}]个客户端.", clientSocket.getInetAddress(), clientList.size());
            executorService.execute(() -> {
                try {
                    log.info("client thread name start: {}", Thread.currentThread().getName());
                    InputStream inputStream = clientSocket.getInputStream();
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    String line = null;
                    while ((line = bufferedReader.readLine()) != null) {
                        log.info("client thread name: {}, send message: {}", Thread.currentThread().getName(), line);
                        broadcastMessage(clientList, line);
                    }
                    log.info("client thread name close connection. : {}, now have[{}] client", Thread.currentThread().getName(), clientList.size());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }

    /**
     * 广播消息
     * @param clientList 所有的客户端
     * @param message 客户端发的消息
     */
    private static void broadcastMessage(List<Socket> clientList, String message) throws IOException {
        for (Socket socket : clientList) {
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(message.getBytes());
            outputStream.flush();
        }
    }
}
